# -*- coding: utf-8 -*-
import rlp
from rlp.sedes import big_endian_int, binary
# from rlp.utils import str_to_bytes, ascii_chr
from .gm.sm2 import Sm2Key
from .utils import signature_to_rsv
import binascii

class Transaction(rlp.Serializable):
    fields = [
        ('region_id', binary),
        ('nonce', big_endian_int),
        ('block_limit', big_endian_int),
        ('target', binary),
        ('data', binary),
    ]
    _fields_set = set(field for field, _ in fields)

    # def __init__(self, region_id, nonce, block_limit, target, data):
    #     self.region_id = region_id
    #     self.nonce = nonce
    #     self.block_limit = block_limit

    #     # target = utils.normalize_address(target, allow_blank=True)
    #     # assert len(target) == 20 or len(target) == 0
    #     self.target = target
    #     self.data = data

class UnverifiedTransaction(rlp.Serializable):
    fields = [
        ('region_id', binary),
        ('nonce', big_endian_int),
        ('block_limit', big_endian_int),
        ('target', binary),
        ('data', binary),
        # ('r', big_endian_int),
        # ('s', big_endian_int),
        # ('v', big_endian_int),
    ]
    _fields_set = set(field for field, _ in fields)

    # def __init__(self, tx):
    #     self.tx = tx
    #     self.r = 0
    #     self.s = 0
    #     self.v = 0

    def sign(self, key):
        sm2_key = Sm2Key(key)
        if sm2_key in (0, '', b'\x00' * 32, '0' * 64):
            raise InvalidTransaction("Zero privkey cannot sign")
        rlp_bytes = rlp.encode(self)

        signature = sm2_key.sign_rsv_with_sm3(binascii.b2a_hex(rlp_bytes))
        print('Signature: ' + signature)
        print('Signature length: %d' % len(signature))
        (r, s, v) = signature_to_rsv(binascii.a2b_hex(signature))

        return VerifiedTransaction(
            region_id = self.region_id,
            nonce = self.nonce,
            block_limit = self.block_limit,
            target = self.target,
            data = self.data,
            r = r, 
            s = s,
            v = v, 
        )

class VerifiedTransaction(rlp.Serializable):
    fields = [
        ('region_id', binary),
        ('nonce', big_endian_int),
        ('block_limit', big_endian_int),
        ('target', binary),
        ('data', binary),
        ('r', big_endian_int),
        ('s', big_endian_int),
        ('v', big_endian_int),
    ]
    
    def rlp_encode(self):
        rlp_bytes = rlp.encode(self)
        return rlp_bytes